﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CNative.Utilities.Function
{
    public class FuncMoney
    {
        /// <summary>
        /// 将数值或人民币转化为大写
        /// </summary>
        /// <param name="num"></param>
        /// <param name="rmbb"></param>
        /// <returns></returns>
        public static String UpperMoney(Double num, bool rmbb)
        {
            bool IsNegative = false;
            if (num < 0) IsNegative = true;
            String[] hz = new String[16];
            String[] money = new String[3];
            //hz[16]="零"
            if (!rmbb)
            {
                hz[1] = "一";
                hz[2] = "二";
                hz[3] = "三";
                hz[4] = "四";
                hz[5] = "五";
                hz[6] = "六";
                hz[7] = "七";
                hz[8] = "八";
                hz[9] = "九";
                hz[10] = "十";
                hz[11] = "百";
                hz[12] = "千";
                hz[13] = "万";
                hz[14] = "亿";
                hz[15] = "点";
            }
            else
            {
                hz[1] = "壹";
                hz[2] = "贰";
                hz[3] = "叁";
                hz[4] = "肆";
                hz[5] = "伍";
                hz[6] = "陆";
                hz[7] = "柒";
                hz[8] = "捌";
                hz[9] = "玖";
                hz[10] = "拾";
                hz[11] = "佰";
                hz[12] = "仟";
                hz[13] = "万";
                hz[14] = "亿";
                hz[15] = "元";
                money[1] = "角";
                money[2] = "分";
            }
            String val, num1, num2;
            num1 = Math.Abs(num).ToString().Trim();
            val = num1;
            while (FuncStr.LeftStr(val, 1) == "0")
            {
                val = FuncStr.RightStr(val, val.Length - 1);
            }
            if (FuncStr.PosStr(val, ".") >= 0)
            {
                num1 = FuncStr.LeftStr(val, FuncStr.PosStr(val, "."));
                num2 = FuncStr.MidStr(val, FuncStr.PosStr(val, ".") + 1);
            }
            else
            {
                num2 = "";
            }

            String strs = "";
            String str_tmp;
            int i;
            for (i = 0; i < num1.Length; i++)
            {
                str_tmp = FuncStr.MidStr(num1, i, 1);
                switch (str_tmp)
                {
                    case "1":
                        strs = strs + hz[1];
                        break;
                    case "2":
                        strs = strs + hz[2];
                        break;
                    case "3":
                        strs = strs + hz[3];
                        break;
                    case "4":
                        strs = strs + hz[4];
                        break;
                    case "5":
                        strs = strs + hz[5];
                        break;
                    case "6":
                        strs = strs + hz[6];
                        break;
                    case "7":
                        strs = strs + hz[7];
                        break;
                    case "8":
                        strs = strs + hz[8];
                        break;
                    case "9":
                        strs = strs + hz[9];
                        break;
                    case "0":
                        strs = strs + "";
                        break;
                }
                if (str_tmp == "0")
                    if ((FuncStr.RightStr(strs, 1) == "零") || (strs == "") || (i == num1.Length - 1))
                    { }//strs = strs;
                    else
                        strs = strs + "零";
                else
                    switch (num1.Length - i)
                    {
                        case 1:
                            //strs = strs;
                            break;
                        case 2:
                        case 6:
                        case 10:
                            strs = strs + hz[10]; //十
                            break;
                        case 3:
                        case 7:
                        case 11:
                            strs = strs + hz[11]; //百
                            break;
                        case 4:
                        case 8:
                        case 12:
                            strs = strs + hz[12]; //千  
                            break;
                        case 5:
                        case 13:
                            strs = strs + hz[13]; //万
                            break;
                        case 9:
                            strs = strs + "亿";
                            break;
                    }

                if ((num1.Length - i == 9) && (FuncStr.MidStr(num1, num1.Length - 9, 1) == "0"))
                {
                    if (FuncStr.RightStr(strs, 1) == "零") strs = FuncStr.LeftStr(strs, strs.Length - 1);
                    strs = strs + "亿";
                }
                if ((num1.Length - i == 5) && (FuncStr.MidStr(num1, num1.Length - 5, 1) == "0"))
                {
                    if (FuncStr.RightStr(strs, 1) == "零") strs = FuncStr.LeftStr(strs, strs.Length - 1);
                    strs = strs + "万";
                }
            }
            if (FuncStr.RightStr(strs, 1) == "零") strs = FuncStr.LeftStr(strs, strs.Length - 1);

            int lpos = FuncStr.PosStr(strs, "亿万");
            if (lpos >= 0) strs = FuncStr.LeftStr(strs, lpos + 1) + FuncStr.MidStr(strs, lpos + 2);
            if (FuncStr.PosStr(val, ".") < 0)
            {
                if (strs == "") strs = "零";

                if (rmbb)
                    return IsNegative == true ? ("负" + strs + hz[15]) : (strs + hz[15]);
                else
                    return IsNegative == true ? ("负" + strs) : strs;
            }
            strs = strs + hz[15];  //点or 元
            int il_i = num2.Length;
            if (rmbb && (il_i > 2)) il_i = 2;
            for (i = 0; i < il_i; i++)
            {
                str_tmp = FuncStr.MidStr(num2, i, 1);
                switch (str_tmp)
                {
                    case "1":
                        strs = strs + hz[1];
                        break;
                    case "2":
                        strs = strs + hz[2];
                        break;
                    case "3":
                        strs = strs + hz[3];
                        break;
                    case "4":
                        strs = strs + hz[4];
                        break;
                    case "5":
                        strs = strs + hz[5];
                        break;
                    case "6":
                        strs = strs + hz[6];
                        break;
                    case "7":
                        strs = strs + hz[7];
                        break;
                    case "8":
                        strs = strs + hz[8];
                        break;
                    case "9":
                        strs = strs + hz[9];
                        break;
                    case "0":
                        strs = strs + "零";
                        break;
                }
                if (rmbb && (FuncStr.RightStr(strs, 1) != "零") && (((FuncStr.RightStr(strs, 1) != "角") && (i == 1)) || ((FuncStr.RightStr(strs, 1) != "元") && (i == 0)))) strs = strs + money[i + 1];
            }
            while (FuncStr.RightStr(strs, 1) == "零")
                strs = FuncStr.LeftStr(strs, strs.Length - 1);

            if (rmbb && FuncStr.LeftStr(strs, 1) == "元")
                strs = FuncStr.RightStr(strs, strs.Length - 1);
            return IsNegative == true ? ("负" + strs) : strs;
        }

        /// <summary>
        /// 舍入算法
        /// </summary>
        /// <param name="val"></param>
        /// <param name="RoundZero">最小值</param>
        /// <param name="RoundFrom">舍入值</param>
        /// <param name="RoundUnit">单位值</param>
        /// <returns>舍入后结果</returns>
        public static double RoundReal(double val, double RoundZero, double RoundFrom, double RoundUnit)
        {
            double AbsVal = Math.Abs(val);

            if (AbsVal < RoundZero)
            {
                AbsVal = 0.0;
            }
            else if (AbsVal <= RoundUnit)
            {
                AbsVal = RoundUnit;
            }
            else
            {
                AbsVal = Math.Floor((AbsVal + RoundUnit - RoundFrom + RoundFrom / 10000) / RoundUnit) * RoundUnit;
            }
            if (val < 0.0)
            {
                AbsVal = -AbsVal;
            }
            return AbsVal;
        }
    }
}
